var fixedBaseWidth = 800


    // 在文档加载前立即执行，防止面板闪烁
    ; (function () {
        const savedState = localStorage.getItem('settingsPanelState');
        const panel = document.getElementById('settings-panel');
        if (panel) {
            if (savedState) {
                const state = JSON.parse(savedState);
                panel.style.left = state.left + 'px';
                panel.style.top = state.top + 'px';
                panel.style.width = state.width + 'px';
                panel.style.height = state.height + 'px';
                if (state.isCollapsed) {
                    panel.classList.add('collapsed');
                }
            }
            panel.style.display = 'block';
        }
    })();
$(document).ready(function () {
    const $imageContainer = $('.image-container');
    const $myImage = $('#myImage');
    const $uploadBtn = $('#uploadBtn');
    const $imageInput = $('#imageInput');
    const $saveBtn = $('#saveBtn');
    const $copyHtmlBtn = $('#copyHtmlBtn');
    const $clearTextBtn = $('#clearTextBtn');
    const $settingsPanel = $('#settings-panel');
    const $settingsInputs = $('#settings-panel input');
    const $dragHandle = $('.drag-handle');
    const $fontColorInput = $('#fontColor');
    const $fontAlphaInput = $('#fontAlpha');
    const $bgColorInput = $('#bgColor');
    const $bgAlphaInput = $('#bgAlpha');
    const $customAlert = $('#custom-alert');
    const $alertMessage = $customAlert.find('.alert-message');
    const $downloadAndUploadBtn = $('#downloadAndUploadBtn');

    const $fontSizeRatioInput = $('#fontSizeRatio');
    const $paddingYRatioInput = $('#paddingYRatio');
    const $paddingXRatioInput = $('#paddingXRatio');
    const $moveStepInput = $('#moveStep');
    const $zIndexInput = $('#zIndex');
    const $borderRadiusInput = $('#borderRadius');

    const $setAllFontSizeBtn = $('#setAllFontSizeBtn');
    const $setAllPaddingYBtn = $('#setAllPaddingYBtn');
    const $setAllPaddingXBtn = $('#setAllPaddingXBtn');
    const $setAllFontColorBtn = $('#setAllFontColorBtn');
    const $setAllBgColorBtn = $('#setAllBgColorBtn');
    const $setAllZIndexBtn = $('#setAllZIndexBtn');
    const $setAllBorderRadiusBtn = $('#setAllBorderRadiusBtn');

    const $htmlContentInput = $('#htmlContentInput');
    const $parseHtmlBtn = $('#parseHtmlBtn');
    const $originalImagePathDisplay = $('#originalImagePathDisplay');
    const $imagePrefixPathInput = $('#imagePrefixPathInput');
    const $copyCustomHtmlBtn = $('#copyCustomHtmlBtn');

    const defaultConfig = {
        fontSizeRatio: 0.025,
        paddingYRatio: 0.004,
        paddingXRatio: 0.004,
        moveStepPercent: 0.5,
        fontColor: '#ffffff',
        fontAlpha: 1,
        bgColor: '#000000',
        bgAlpha: 0.5,
        zIndex: 10,
        borderRadius: 5,
        copyHtmlBtnText: '复制内容',
        copyHtmlBtnSuccessText: '已复制内容',
        copyCustomHtmlBtnText: '复制自定路径图片内容',
        copyCustomHtmlBtnSuccessText: "已复制自定路径图片内容"
    };

    const baseImageWidth = 800;
    let currentImageAspectRatio = 1;
    let originalImageWidth = 0;
    let originalImageHeight = 0;

    let isDragging = false;
    let dragTimeout = null;
    const dragDelay = 500;
    let alertTimeout = null;

    function showAlert(message, duration = 2000) {
        clearTimeout(alertTimeout);
        $alertMessage.text(message);
        $customAlert.addClass('show');
        alertTimeout = setTimeout(() => {
            $customAlert.removeClass('show');
        }, duration);
    }

    function hexToRgba(hex, alpha) {
        if (!hex || hex === 'transparent') {
            return `rgba(0, 0, 0, 0)`;
        }
        const r = parseInt(hex.slice(1, 3), 16);
        const g = parseInt(hex.slice(3, 5), 16);
        const b = parseInt(hex.slice(5, 7), 16);
        return `rgba(${r}, ${g}, ${b}, ${alpha})`;
    }

    function rgbaToHex(rgba) {
        if (rgba === 'transparent' || rgba.startsWith('rgba(0, 0, 0, 0)')) {
            return '#000000';
        }
        const parts = rgba.match(/\d+/g);
        if (!parts || parts.length < 3) return '#000000';
        const [r, g, b] = parts.map(Number);
        const toHex = (c) => `0${c.toString(16)}`.slice(-2);
        return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
    }

    function rgbaToAlpha(rgba) {
        if (rgba === 'transparent' || rgba.startsWith('rgba(0, 0, 0, 0)')) {
            return 0;
        }
        const parts = rgba.match(/[\d.]+/g);
        if (!parts || parts.length < 4) return 1;
        return parseFloat(parts[3]);
    }

    function saveTextItems() {
        const textItemsData = [];
        const containerWidth = $imageContainer.width();
        const containerHeight = $imageContainer.height();
        $('.text-item').each(function () {
            const $this = $(this);
            const padding = $this.css('padding').split(' ').map(p => parseFloat(p) / containerWidth);
            textItemsData.push({
                text: this.innerText,
                left: parseFloat($this.css('left')) / containerWidth * 100,
                top: parseFloat($this.css('top')) / containerHeight * 100,
                fontSizeRatio: parseFloat($this.css('font-size')) / containerWidth,
                paddingYRatio: padding.length > 1 ? padding[0] : padding[0],
                paddingXRatio: padding.length > 1 ? padding[1] : padding[0],
                color: $this.css('color'),
                backgroundColor: $this.css('background-color'),
                zIndex: $this.css('z-index'),
                borderRadius: parseFloat($this.css('border-radius')) / containerWidth
            });
        });
        localStorage.setItem('textItemsData', JSON.stringify(textItemsData));
    }

    function loadTextItems() {
        const savedData = localStorage.getItem('textItemsData');
        if (savedData) {
            const textItemsData = JSON.parse(savedData);
            const containerWidth = $imageContainer.width();
            textItemsData.forEach(item => {
                const $textItem = $('<div class="text-item" contenteditable="false"></div>');
                const htmlContent = item.text.replace(/\n/g, '<br>');
                $textItem.html(htmlContent);
                $textItem.css({
                    'left': item.left + '%',
                    'top': item.top + '%',
                    'font-size': (item.fontSizeRatio * containerWidth) + 'px',
                    'padding': `${(item.paddingYRatio * containerWidth)}px ${(item.paddingXRatio * containerWidth)}px`,
                    'color': item.color,
                    'background-color': item.backgroundColor,
                    'z-index': item.zIndex,
                    'border-radius': (item.borderRadius * containerWidth) + 'px'
                });
                $imageContainer.append($textItem);
            });
            initDraggableTextItems();
        }
    }

    function getSettings() {
        const fontSizeRatio = parseFloat($fontSizeRatioInput.val());
        const paddingYRatio = parseFloat($paddingYRatioInput.val());
        const paddingXRatio = parseFloat($paddingXRatioInput.val());
        const moveStepPercent = parseFloat($moveStepInput.val());
        const fontColorHex = $fontColorInput.val();
        const fontAlpha = parseFloat($fontAlphaInput.val());
        const bgColorHex = $bgColorInput.val();
        const bgAlpha = parseFloat($bgAlphaInput.val());
        const zIndex = parseInt($zIndexInput.val());
        const borderRadius = parseInt($borderRadiusInput.val());
        return {
            fontSizeRatio: isNaN(fontSizeRatio) ? defaultConfig.fontSizeRatio : fontSizeRatio,
            paddingYRatio: isNaN(paddingYRatio) ? defaultConfig.paddingYRatio : paddingYRatio,
            paddingXRatio: isNaN(paddingXRatio) ? defaultConfig.paddingXRatio : paddingXRatio,
            moveStepPercent: isNaN(moveStepPercent) ? defaultConfig.moveStepPercent : moveStepPercent,
            fontColor: fontColorHex || defaultConfig.fontColor,
            fontAlpha: isNaN(fontAlpha) ? defaultConfig.fontAlpha : fontAlpha,
            bgColor: bgColorHex || defaultConfig.bgColor,
            bgAlpha: isNaN(bgAlpha) ? defaultConfig.bgAlpha : bgAlpha,
            zIndex: isNaN(zIndex) ? defaultConfig.zIndex : zIndex,
            borderRadius: isNaN(borderRadius) ? defaultConfig.borderRadius : borderRadius,
            copyHtmlBtnText: defaultConfig.copyHtmlBtnText,
            copyCustomHtmlBtnText: defaultConfig.copyCustomHtmlBtnText,
            copyHtmlBtnSuccessText: defaultConfig.copyHtmlBtnSuccessText,
            copyCustomHtmlBtnSuccessText: defaultConfig.copyCustomHtmlBtnSuccessText
        };
    }

    function saveSettings(config) {
        localStorage.setItem('settingsPanelConfig', JSON.stringify(config));
    }

    function loadAndApplySettings() {
        const savedConfig = localStorage.getItem('settingsPanelConfig');
        const configToApply = savedConfig ? JSON.parse(savedConfig) : defaultConfig;
        $fontSizeRatioInput.val(configToApply.fontSizeRatio);
        $paddingYRatioInput.val(configToApply.paddingYRatio);
        $paddingXRatioInput.val(configToApply.paddingXRatio);
        $moveStepInput.val(configToApply.moveStepPercent);
        $fontColorInput.val(configToApply.fontColor);
        $fontAlphaInput.val(configToApply.fontAlpha);
        $bgColorInput.val(configToApply.bgColor);
        $bgAlphaInput.val(configToApply.bgAlpha);
        $zIndexInput.val(configToApply.zIndex);
        $borderRadiusInput.val(configToApply.borderRadius);
        $copyHtmlBtn.text(configToApply.copyHtmlBtnText);
    }

    (function loadFromLocalStorage() {
        const savedImage = localStorage.getItem('savedImage');
        const savedAspectRatio = localStorage.getItem('imageAspectRatio');
        const savedOriginalWidth = localStorage.getItem('originalImageWidth');
        const savedOriginalHeight = localStorage.getItem('originalImageHeight');
        const savedImagePath = localStorage.getItem('originalImagePath');

        $("#imagePrefixPathInput").val(localStorage.getItem('imagePrefixPath'));

        if (savedImage && savedAspectRatio && savedOriginalWidth && savedOriginalHeight) {
            currentImageAspectRatio = parseFloat(savedAspectRatio);
            originalImageWidth = parseInt(savedOriginalWidth);
            originalImageHeight = parseInt(savedOriginalHeight);
            $myImage.css('width', baseImageWidth + 'px');
            $myImage.css('height', (baseImageWidth / currentImageAspectRatio) + 'px');
            $imageContainer.css('height', (baseImageWidth / currentImageAspectRatio) + 'px');
            $myImage.attr('src', savedImage);
            loadTextItems();
            if (savedImagePath) {
                $originalImagePathDisplay.val(savedImagePath);
            }
            showAlert('已从上次的会话中恢复图片和标注');
        } else {
            loadTextItems();
        }
    })();

    $settingsInputs.on('change', function () {
        saveSettings(getSettings());
    });
    loadAndApplySettings();

    // 双击编辑图片前缀路径输入框
    $('#imagePrefixPathInput').on('dblclick', function () {
        $(this).prop('readonly', false).focus();
    });
    // 失去焦点后重新设为只读
    $('#imagePrefixPathInput').on('blur', function () {
        $(this).prop('readonly', true);
    });

    $uploadBtn.on('click', function () {
        $imageInput.trigger('click');
    });
    $imageInput.on('change', function () {
        const file = this.files[0];
        if (file) {
            const reader = new FileReader();
            reader.onload = function (e) {
                const imageDataURL = e.target.result;
                const tempImage = new Image();
                tempImage.onload = function () {
                    originalImageWidth = this.naturalWidth;
                    originalImageHeight = this.naturalHeight;
                    currentImageAspectRatio = originalImageWidth / originalImageHeight;

                    localStorage.setItem('imageAspectRatio', currentImageAspectRatio);
                    localStorage.setItem('originalImageWidth', originalImageWidth);
                    localStorage.setItem('originalImageHeight', originalImageHeight);


                    let newImagePrefixPath = getFileNameAndPathRegex(file.name).directoryPath
                    let newOriginalImagePath = getFileNameAndPathRegex(file.name).fileName
                    localStorage.setItem('originalImagePath', newOriginalImagePath);
                    localStorage.setItem('imagePrefixPath', newImagePrefixPath || localStorage.getItem('imagePrefixPath') || "");
                    debugger
                    $("#imagePrefixPathInput").val(localStorage.getItem('imagePrefixPath'));
                    $originalImagePathDisplay.val(newOriginalImagePath);



                    $myImage.css('width', baseImageWidth + 'px');
                    $myImage.css('height', (baseImageWidth / currentImageAspectRatio) + 'px');
                    $imageContainer.css('height', (baseImageWidth / currentImageAspectRatio) + 'px');
                    $myImage.attr('src', imageDataURL);
                    localStorage.setItem('savedImage', imageDataURL);

                    $('.text-item').remove();
                    localStorage.removeItem('textItemsData');
                    showAlert('图片已上传并缓存，可以开始标注了!');
                };
                tempImage.src = imageDataURL;
            };
            reader.readAsDataURL(file);
        }
    });
    $imageContainer.on('click', '.text-item', function (e) {
        e.stopPropagation();

        const $this = $(this);

        if ($this.data('isDragged')) {
            $this.data('isDragged', false);
            return;
        }

        const imageWidth = $imageContainer.width();
        const textFontSize = parseFloat($this.css('font-size'));
        const padding = $this.css('padding').split(' ').map(parseFloat);
        const borderRadius = parseFloat($this.css('border-radius'));

        $fontSizeRatioInput.val((textFontSize / imageWidth).toFixed(4));
        $paddingYRatioInput.val((padding[0] / imageWidth).toFixed(4));
        $paddingXRatioInput.val(((padding.length > 1 ? padding[1] : padding[0]) / imageWidth).toFixed(4));
        $borderRadiusInput.val(borderRadius);

        $fontColorInput.val(rgbaToHex($this.css('color')));
        $fontAlphaInput.val(rgbaToAlpha($this.css('color')));
        $bgColorInput.val(rgbaToHex($this.css('background-color')));
        $bgAlphaInput.val(rgbaToAlpha($this.css('background-color')));

        const zIndexValue = $this.css('z-index');
        const parsedZIndex = parseInt(zIndexValue, 10);
        $zIndexInput.val(isNaN(parsedZIndex) ? defaultConfig.zIndex : parsedZIndex);

        $('.text-item').removeClass('editing selected').attr('contenteditable', 'false');

        $this.addClass('editing selected').attr('contenteditable', 'true').focus();
        if (document.createRange && window.getSelection) {
            const range = document.createRange();
            const selection = window.getSelection();
            range.selectNodeContents(this);
            range.collapse(false);
            selection.removeAllRanges();
            selection.addRange(range);
        }
    });
    $fontColorInput.on('input', function () {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length > 0) {
            const newColor = hexToRgba($(this).val(), $fontAlphaInput.val());
            $selectedItem.css('color', newColor);
            saveTextItems();
            $selectedItem.focus();
        }
    });
    $fontAlphaInput.on('input', function () {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length > 0) {
            const newColor = hexToRgba($fontColorInput.val(), $(this).val());
            $selectedItem.css('color', newColor);
            saveTextItems();
            $selectedItem.focus();
        }
    });
    $bgColorInput.on('input', function () {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length > 0) {
            const newColor = hexToRgba($(this).val(), $bgAlphaInput.val());
            $selectedItem.css('background-color', newColor);
            saveTextItems();
            $selectedItem.focus();
        }
    });
    $bgAlphaInput.on('input', function () {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length > 0) {
            const newColor = hexToRgba($bgColorInput.val(), $(this).val());
            $selectedItem.css('background-color', newColor);
            saveTextItems();
            $selectedItem.focus();
        }
    });
    $fontSizeRatioInput.on('input', function () {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length > 0) {
            const imageWidth = $imageContainer.width();
            const newFontSize = imageWidth * parseFloat($(this).val());
            $selectedItem.css('font-size', newFontSize + 'px');
            saveTextItems();
            $selectedItem.focus();
        }
    });

    $paddingYRatioInput.on('input', function () {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length > 0) {
            const imageWidth = $imageContainer.width();
            const newPaddingY = imageWidth * parseFloat($(this).val());
            const newPaddingX = imageWidth * parseFloat($paddingXRatioInput.val());
            $selectedItem.css('padding', `${newPaddingY}px ${newPaddingX}px`);
            saveTextItems();
            $selectedItem.focus();
        }
    });
    $paddingXRatioInput.on('input', function () {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length > 0) {
            const imageWidth = $imageContainer.width();
            const newPaddingY = imageWidth * parseFloat($paddingYRatioInput.val());
            const newPaddingX = imageWidth * parseFloat($(this).val());
            $selectedItem.css('padding', `${newPaddingY}px ${newPaddingX}px`);
            saveTextItems();
            $selectedItem.focus();
        }
    });
    $zIndexInput.on('input', function () {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length > 0) {
            const newZIndex = parseInt($(this).val());
            if (!isNaN(newZIndex)) {
                $selectedItem.css('z-index', newZIndex);
                saveTextItems();
                $selectedItem.focus();
            }
        }
    });
    $borderRadiusInput.on('input', function () {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length > 0) {
            const newBorderRadius = parseInt($(this).val());
            if (!isNaN(newBorderRadius)) {
                $selectedItem.css('border-radius', newBorderRadius + 'px');
                saveTextItems();
                $selectedItem.focus();
            }
        }
    });
    $setAllFontSizeBtn.on('click', function () {
        const imageWidth = $imageContainer.width();
        const newFontSize = imageWidth * parseFloat($fontSizeRatioInput.val());
        if (!isNaN(newFontSize)) {
            $('.text-item').css('font-size', newFontSize + 'px');
            saveTextItems();
            showAlert('所有文本框的字体大小已更新!');
        }
    });
    $setAllPaddingYBtn.on('click', function () {
        const imageWidth = $imageContainer.width();
        const newPaddingY = imageWidth * parseFloat($paddingYRatioInput.val());
        if (!isNaN(newPaddingY)) {
            $('.text-item').each(function () {
                const $this = $(this);
                const currentPaddingX = parseFloat($this.css('padding-left'));
                $this.css('padding', `${newPaddingY}px ${currentPaddingX}px`);
            });
            saveTextItems();
            showAlert('所有文本框的上下内边距已更新!');
        }
    });
    $setAllPaddingXBtn.on('click', function () {
        const imageWidth = $imageContainer.width();
        const newPaddingX = imageWidth * parseFloat($paddingXRatioInput.val());
        if (!isNaN(newPaddingX)) {
            $('.text-item').each(function () {
                const $this = $(this);
                const currentPaddingY = parseFloat($this.css('padding-top'));
                $this.css('padding', `${currentPaddingY}px ${newPaddingX}px`);
            });
            saveTextItems();
            showAlert('所有文本框的左右内边距已更新!');
        }
    });
    $setAllFontColorBtn.on('click', function () {
        const newColor = hexToRgba($fontColorInput.val(), $fontAlphaInput.val());
        if (newColor) {
            $('.text-item').css('color', newColor);
            saveTextItems();
            showAlert('所有文本框的字体颜色已更新!');
        }
    });
    $setAllBgColorBtn.on('click', function () {
        const newColor = hexToRgba($bgColorInput.val(), $bgAlphaInput.val());
        if (newColor) {
            $('.text-item').css('background-color', newColor);
            saveTextItems();
            showAlert('所有文本框的底色已更新!');
        }
    });
    $setAllZIndexBtn.on('click', function () {
        const newZIndex = parseInt($zIndexInput.val());
        if (!isNaN(newZIndex)) {
            $('.text-item').css('z-index', newZIndex);
            saveTextItems();
            showAlert('所有文本框的层级已更新!');
        } else {
            showAlert('请输入有效的层级值');
        }
    });
    $setAllBorderRadiusBtn.on('click', function () {
        const newBorderRadius = parseInt($borderRadiusInput.val());
        if (!isNaN(newBorderRadius)) {
            $('.text-item').css('border-radius', newBorderRadius + 'px');
            saveTextItems();
            showAlert('所有文本框的圆角已更新!');
        } else {
            showAlert('请输入有效的圆角值');
        }
    });
    $clearTextBtn.on('click', function () {
        if (confirm('确定要清除所有文本标注吗？此操作不可恢复。')) {
            localStorage.removeItem('textItemsData');
            $('.text-item').remove();
            showAlert('已成功清除所有文本标注，图片已保留。');
        }
    });
    $settingsPanel.draggable({
        handle: '.drag-handle',
        containment: 'body',
        start: function () {
            $(this).data('isDragging', true);
        },
        stop: function (event, ui) {
            const state = {
                left: ui.position.left,
                top: ui.position.top,
                width: $settingsPanel.width(),
                height: $settingsPanel.height(),
                isCollapsed: $settingsPanel.hasClass('collapsed')
            };
            localStorage.setItem('settingsPanelState', JSON.stringify(state));
            $(this).data('isDragging', false);
        }
    }).resizable({
        handles: 'all',
        minWidth: 200,
        minHeight: 200,
        stop: function (event, ui) {
            const state = {
                left: ui.position.left,
                top: ui.position.top,
                width: ui.size.width,
                height: ui.size.height,
                isCollapsed: $settingsPanel.hasClass('collapsed')
            };
            localStorage.setItem('settingsPanelState', JSON.stringify(state));
        }
    });

    let hoverTimeout = null;
    $dragHandle.on('mouseenter', function () {
        clearTimeout(hoverTimeout);
        hoverTimeout = setTimeout(function () {
            $settingsPanel.addClass('panel-active');
        }, 300);
    });
    $settingsPanel.on('mouseleave', function () {
        clearTimeout(hoverTimeout);
        $settingsPanel.removeClass('panel-active');
    });
    $settingsPanel.on('click', function (e) {
        if ($(this).data('isDragging')) {
            return;
        }
        const isHandleOrCollapsed = $(e.target).is($dragHandle) || $(e.target).is($settingsPanel.filter('.collapsed'));
        if (isHandleOrCollapsed) {
            e.stopPropagation();
            const isCollapsed = $settingsPanel.hasClass('collapsed');
            $settingsPanel.toggleClass('collapsed');
            const state = {
                left: $settingsPanel.offset().left,
                top: $settingsPanel.offset().top,
                width: $settingsPanel.width(),
                height: $settingsPanel.height(),
                isCollapsed: !isCollapsed
            };
            localStorage.setItem('settingsPanelState', JSON.stringify(state));
        }
    });
    function initDraggableTextItems() {
        $('.text-item').draggable({
            containment: 'parent',
            helper: function (event) {
                if (event.altKey) {
                    const $clone = $(this).clone()
                        .removeClass('editing selected')
                        .data('isClone', true)
                        .removeAttr('id');
                    return $clone;
                }
                return $(this);
            },
            start: function (event, ui) {
                isDragging = true;
                $(this).data({
                    'isDragged': false,
                    'startTop': ui.position.top,
                    'startLeft': ui.position.left,
                    'isDraggingVertically': false,
                    'isDraggingHorizontally': false,
                    'isAltDrag': event.altKey
                });
            },
            drag: function (event, ui) {
                const $this = $(this);
                if (Math.abs(ui.originalPosition.top - ui.position.top) > 5 ||
                    Math.abs(ui.originalPosition.left - ui.position.left) > 5) {
                    $this.data('isDragged', true);
                }

                if ($this.data('isAltDrag')) {
                    const startTop = $this.data('startTop');
                    const startLeft = $this.data('startLeft');
                    const currentTop = ui.position.top;
                    const currentLeft = ui.position.left;
                    if (!$this.data('isDraggingVertically') && !$this.data('isDraggingHorizontally')) {
                        const deltaX = Math.abs(currentLeft - startLeft);
                        const deltaY = Math.abs(currentTop - startTop);
                        if (deltaX > 5 && deltaX > deltaY) {
                            $this.data('isDraggingHorizontally', true);
                        } else if (deltaY > 5 && deltaY > deltaX) {
                            $this.data('isDraggingVertically', true);
                        }
                    }

                    if ($this.data('isDraggingHorizontally')) {
                        ui.position.top = startTop;
                    } else if ($this.data('isDraggingVertically')) {
                        ui.position.left = startLeft;
                    }
                }
            },
            stop: function (event, ui) {
                const $this = $(this);
                const isAltDrag = $this.data('isAltDrag');

                if (isAltDrag && ui.helper.data('isClone')) {
                    const $newElement = ui.helper;
                    const updatedContainerWidth = $imageContainer.width();
                    const updatedContainerHeight = $imageContainer.height();
                    const newLeft = (ui.position.left / updatedContainerWidth) * 100;
                    const newTop = (ui.position.top / updatedContainerHeight) * 100;

                    $newElement.css({
                        'left': newLeft + '%',
                        'top': newTop + '%'
                    });
                    $newElement.html($this.html());
                    $newElement.css({
                        'font-size': $this.css('font-size'),
                        'padding': $this.css('padding'),
                        'color': $this.css('color'),
                        'background-color': $this.css('background-color'),
                        'z-index': $this.css('z-index'),
                        'border-radius': $this.css('border-radius')
                    });
                    $imageContainer.append($newElement);
                    initDraggableTextItems();
                } else {
                    const updatedContainerWidth = $imageContainer.width();
                    const updatedContainerHeight = $imageContainer.height();
                    const newLeft = (ui.position.left / updatedContainerWidth) * 100;
                    const newTop = (ui.position.top / updatedContainerHeight) * 100;
                    $(this).css({
                        'left': newLeft + '%',
                        'top': newTop + '%'
                    });
                }
                saveTextItems();
                isDragging = false;
                dragTimeout = setTimeout(() => {
                    isDragging = false;
                }, dragDelay);
            }
        });
    }

    $imageContainer.on('click', function (e) {
        if (isDragging) {
            return;
        }

        const $target = $(e.target);

        if (!$target.closest('.text-item').length) {
            const $selectedItem = $('.text-item.selected');

            if ($selectedItem.length > 0) {
                $selectedItem.removeClass('editing selected').attr('contenteditable', 'false');
            } else {
                const settings = getSettings();
                const $textItem = $('<div class="text-item" contenteditable="false"></div>');
                $imageContainer.append($textItem);
                const imageWidth = $imageContainer.width();
                const newFontSize = imageWidth * settings.fontSizeRatio;
                const newPaddingY = imageWidth * settings.paddingYRatio;
                const newPaddingX = imageWidth * settings.paddingXRatio;
                const fontColor = hexToRgba(settings.fontColor, settings.fontAlpha);
                const bgColor = hexToRgba(settings.bgColor, settings.bgAlpha);
                const zIndex = settings.zIndex;
                const borderRadius = settings.borderRadius;

                $textItem.css({
                    'font-size': newFontSize + 'px',
                    'padding': `${newPaddingY}px ${newPaddingX}px`,
                    'color': fontColor,
                    'background-color': bgColor,
                    'z-index': zIndex,
                    'border-radius': borderRadius + 'px'
                });
                const clickX = e.pageX - $imageContainer.offset().left;
                const clickY = e.pageY - $imageContainer.offset().top;
                const textItemWidth = $textItem.outerWidth();
                const textItemHeight = $textItem.outerHeight();
                const adjustedX = clickX - textItemWidth / 2;
                const adjustedY = clickY - textItemHeight / 2;
                const percentX = (adjustedX / $imageContainer.width()) * 100;
                const percentY = (adjustedY / $imageContainer.height()) * 100;
                $textItem.css({
                    'left': percentX + '%',
                    'top': percentY + '%'
                });
                $textItem.attr('contenteditable', 'true').addClass('editing selected').focus();
                if (document.createRange && window.getSelection) {
                    const range = document.createRange();
                    const selection = window.getSelection();
                    range.selectNodeContents($textItem[0]);
                    range.collapse(false);
                    selection.removeAllRanges();
                    selection.addRange(range);
                }

                initDraggableTextItems();
                saveTextItems();
            }
        }
    });

    const longPressTimers = new Map();
    const shortPressState = new Map();

    $imageContainer.on('keydown', function (e) {
        const $selectedItem = $('.text-item.selected');
        if ($selectedItem.length === 0) {
            return;
        }

        const settings = getSettings();
        if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key) && !$(e.target).closest('#settings-panel').length) {
            e.preventDefault();

            const currentTop = parseFloat($selectedItem.css('top'));
            const currentLeft = parseFloat($selectedItem.css('left'));
            const containerWidth = $imageContainer.width();
            const containerHeight = $imageContainer.height();
            let newTop = currentTop;
            let newLeft = currentLeft;

            const moveStep = (settings.moveStepPercent / 100);

            if (e.key === 'ArrowUp') {
                newTop = Math.max(0, currentTop - moveStep * containerHeight);
            } else if (e.key === 'ArrowDown') {
                const itemHeight = $selectedItem.outerHeight();
                newTop = Math.min(containerHeight - itemHeight, currentTop + moveStep * containerHeight);
            } else if (e.key === 'ArrowLeft') {
                newLeft = Math.max(0, currentLeft - moveStep * containerWidth);
            } else if (e.key === 'ArrowRight') {
                const itemWidth = $selectedItem.outerWidth();
                newLeft = Math.min(containerWidth - itemWidth, currentLeft + moveStep * containerWidth);
            }

            $selectedItem.css('top', (newTop / containerHeight) * 100 + '%');
            $selectedItem.css('left', (newLeft / containerWidth) * 100 + '%');
            saveTextItems();
        }
    });
    $imageContainer.on('keydown', '.text-item', function (e) {
        e.stopPropagation();

        const $this = $(this);
        const element = $this[0];
        if ($this.hasClass('editing') && e.altKey) {
            if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
                e.preventDefault();
                const settings = getSettings();
                const currentTop = parseFloat($this.css('top'));
                const currentLeft = parseFloat($this.css('left'));
                const containerWidth = $imageContainer.width();
                const containerHeight = $imageContainer.height();
                let newTop = currentTop;
                let newLeft = currentLeft;
                const moveStep = (settings.moveStepPercent / 100);
                if (e.key === 'ArrowUp') {
                    newTop = Math.max(0, currentTop - moveStep * containerHeight);
                } else if (e.key === 'ArrowDown') {
                    const itemHeight = $this.outerHeight();
                    newTop = Math.min(containerHeight - itemHeight, currentTop + moveStep * containerHeight);
                } else if (e.key === 'ArrowLeft') {
                    newLeft = Math.max(0, currentLeft - moveStep * containerWidth);
                } else if (e.key === 'ArrowRight') {
                    const itemWidth = $this.outerWidth();
                    newLeft = Math.min(containerWidth - itemWidth, currentLeft + moveStep * containerWidth);
                }
                $this.css('top', (newTop / containerHeight) * 100 + '%');
                $this.css('left', (newLeft / containerWidth) * 100 + '%');
                saveTextItems();
                return;
            }
        }
        if ($this.text().trim() === '' && (e.key === 'Backspace' || e.key === 'Delete')) {
            const now = new Date().getTime();
            if (!longPressTimers.has(element)) {
                const timer = setTimeout(() => {
                    $this.remove();
                    longPressTimers.delete(element);
                    shortPressState.delete(element);
                    saveTextItems();
                }, 1000);
                longPressTimers.set(element, timer);
            }
            let state = shortPressState.get(element) || {
                count: 0,
                lastTime: 0,
                firstTime: now
            };
            const timeSinceLastPress = now - state.lastTime;
            if (timeSinceLastPress > 50) {
                state.count++;
                state.lastTime = now;
            } else {
                state.count = 1;
                state.lastTime = now;
                state.firstTime = now;
            }
            shortPressState.set(element, state);
            const totalTime = now - state.firstTime;
            if (state.count >= 4 && totalTime < 1000) {
                clearTimeout(longPressTimers.get(element));
                $this.remove();
                shortPressState.delete(element);
                longPressTimers.delete(element);
                saveTextItems();
            }
        }
    });
    $imageContainer.on('keyup', '.text-item', function (e) {
        const $this = $(this);
        const element = $this[0];
        if ((e.key === 'Backspace' || e.key === 'Delete') && longPressTimers.has(element)) {
            clearTimeout(longPressTimers.get(element));
            longPressTimers.delete(element);
        }
        saveTextItems();
    });
    $imageContainer.on('blur', '.text-item', function () {
        const $this = $(this);
        if ($this.text().trim() === '') {
            $this.remove();
            saveTextItems();
        } else {
            $this.attr('contenteditable', 'false').removeClass('editing');
            saveTextItems();
        }
    });

    $saveBtn.on('click', function () {
        const image = $myImage[0];
        const imageContainer = $imageContainer[0];

        image.crossOrigin = 'anonymous';

        const loadImage = new Promise((resolve, reject) => {
            if (image.complete && image.naturalHeight !== 0) {
                resolve(image);
            } else {
                image.onload = () => resolve(image);
                image.onerror = () => reject('图片加载失败，无法保存。');
            }
        });

        loadImage.then(loadedImage => {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');

            canvas.width = originalImageWidth;
            canvas.height = originalImageHeight;

            ctx.drawImage(loadedImage, 0, 0, originalImageWidth, originalImageHeight);

            const scaleFactorX = originalImageWidth / imageContainer.clientWidth;
            const scaleFactorY = originalImageHeight / imageContainer.clientHeight;
            $('.text-item').each(function () {
                const $this = $(this);
                const textContent = this.innerText;

                const liveTopPx = parseFloat($this.css('top'));
                const liveLeftPx = parseFloat($this.css('left'));
                const liveFontSizePx = parseFloat($this.css('font-size'));
                const liveColor = $this.css('color');
                const liveBgColor = $this.css('background-color');
                const livePaddingPx = $this.css('padding').split(' ').map(parseFloat);


                const scaledTop = liveTopPx * scaleFactorY;
                const scaledLeft = liveLeftPx * scaleFactorX;
                const scaledFontSize = liveFontSizePx * scaleFactorX;
                const scaledPaddingY = livePaddingPx[0] * scaleFactorY;
                const scaledPaddingX = livePaddingPx.length > 1 ? livePaddingPx[1] * scaleFactorX : scaledPaddingY;

                ctx.font = `bold ${scaledFontSize}px Arial, sans-serif`;
                const lines = textContent.split('\n');

                if (liveBgColor !== 'transparent' && rgbaToAlpha(liveBgColor) > 0) {
                    ctx.fillStyle = liveBgColor;
                    let totalTextWidth = 0;
                    let lineHeights = 0;
                    lines.forEach(line => {
                        const metrics = ctx.measureText(line);
                        totalTextWidth = Math.max(totalTextWidth, metrics.width);
                        lineHeights += scaledFontSize * 1.2;
                    });
                    ctx.fillRect(scaledLeft, scaledTop, totalTextWidth + scaledPaddingX * 2, lineHeights + scaledPaddingY * 2);
                }

                ctx.fillStyle = liveColor;
                ctx.shadowColor = 'rgba(0, 0, 0, 0.7)';
                ctx.shadowBlur = 4;
                ctx.shadowOffsetX = 2;
                ctx.shadowOffsetY = 2;
                ctx.textAlign = 'left';
                ctx.textBaseline = 'top';

                let lineY = scaledTop + scaledPaddingY;
                const lineHeight = scaledFontSize * 1.2;
                lines.forEach(line => {
                    ctx.fillText(line, scaledLeft + scaledPaddingX, lineY);
                    lineY += lineHeight;
                });
            });

            try {
                const dataURL = canvas.toDataURL('image/png');
                const link = document.createElement('a');
                link.download = 'edited_image.png';
                link.href = dataURL;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                showAlert('图片已成功保存!');
            } catch (e) {
                console.error('保存失败：', e);
                showAlert('保存失败！如果您通过本地文件打开，请使用本地服务器运行。');
            }
        }).catch(error => {
            console.error(error);
            showAlert(error);
        });
    });

    $downloadAndUploadBtn.on('click', function () {
        const image = $myImage[0];
        const imageContainer = $imageContainer[0];
        image.crossOrigin = 'anonymous';

        const loadImage = new Promise((resolve, reject) => {
            if (image.complete && image.naturalHeight !== 0) {
                resolve(image);
            } else {
                image.onload = () => resolve(image);
                image.onerror = () => reject('图片加载失败，无法生成可上传图片。');
            }
        });

        loadImage.then(loadedImage => {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            canvas.width = originalImageWidth;
            canvas.height = originalImageHeight;
            ctx.drawImage(loadedImage, 0, 0, originalImageWidth, originalImageHeight);
            const scaleFactorX = originalImageWidth / imageContainer.clientWidth;
            const scaleFactorY = originalImageHeight / imageContainer.clientHeight;
            $('.text-item').each(function () {
                const $this = $(this);
                const textContent = this.innerText;
                const liveTopPx = parseFloat($this.css('top'));
                const liveLeftPx = parseFloat($this.css('left'));
                const liveFontSizePx = parseFloat($this.css('font-size'));
                const liveColor = $this.css('color');
                const liveBgColor = $this.css('background-color');
                const livePaddingPx = $this.css('padding').split(' ').map(parseFloat);
                const liveBorderRadiusPx = parseFloat($this.css('border-radius'));


                const scaledTop = liveTopPx * scaleFactorY;
                const scaledLeft = liveLeftPx * scaleFactorX;
                const scaledFontSize = liveFontSizePx * scaleFactorX;
                const scaledPaddingY = livePaddingPx[0] * scaleFactorY;
                const scaledPaddingX = livePaddingPx.length > 1 ? livePaddingPx[1] * scaleFactorX : scaledPaddingY;
                const scaledBorderRadius = liveBorderRadiusPx * scaleFactorX;

                ctx.font = `bold ${scaledFontSize}px Arial, sans-serif`;

                const lines = textContent.split('\n');
                if (liveBgColor !== 'transparent' && rgbaToAlpha(liveBgColor) > 0) {
                    ctx.fillStyle = liveBgColor;
                    let totalTextWidth = 0;
                    let lineHeights = 0;
                    lines.forEach(line => {
                        const metrics = ctx.measureText(line);
                        totalTextWidth = Math.max(totalTextWidth, metrics.width);
                        lineHeights += scaledFontSize * 1.2;
                    });
                    function drawRoundRect(x, y, w, h, radius) {
                        const r = Math.min(radius, w / 2, h / 2);
                        ctx.beginPath();
                        ctx.moveTo(x + r, y);
                        ctx.arcTo(x + w, y, x + w, y + h, r);
                        ctx.arcTo(x + w, y + h, x, y + h, r);
                        ctx.arcTo(x, y + h, x, y, r);
                        ctx.arcTo(x, y, x + w, y, r);
                        ctx.closePath();
                        ctx.fill();
                    }

                    drawRoundRect(scaledLeft, scaledTop, totalTextWidth + scaledPaddingX * 2, lineHeights + scaledPaddingY * 2, scaledBorderRadius);
                }

                ctx.fillStyle = liveColor;
                ctx.shadowColor = 'rgba(0, 0, 0, 0.7)';
                ctx.shadowBlur = 4;
                ctx.shadowOffsetX = 2;
                ctx.shadowOffsetY = 2;
                ctx.textAlign = 'left';
                ctx.textBaseline = 'top';

                let lineY = scaledTop + scaledPaddingY;
                const lineHeight = scaledFontSize * 1.2;
                lines.forEach(line => {
                    ctx.fillText(line, scaledLeft + scaledPaddingX, lineY);
                    lineY += lineHeight;
                });
            });

            try {
                canvas.toBlob(function (blob) {
                    if (blob) {
                        const link = document.createElement('a');
                        link.download = 'edited_image.png';
                        link.href = URL.createObjectURL(blob);
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);
                        URL.revokeObjectURL(link.href);
                        showAlert('图片已下载，可以上传了!');
                    } else {
                        showAlert('无法生成可上传图片，请重试。');
                    }
                }, 'image/png');
            } catch (e) {
                console.error('生成图片失败：', e);
                showAlert('生成图片失败！如果您通过本地文件打开，请使用本地服务器运行。');
            }
        }).catch(error => {
            console.error(error);
            showAlert(error);
        });
    });

    const generateHtml = (imageSrc) => {
        const textItemsHtml = [];
        const containerWidth = $imageContainer.width();
        const containerHeight = $imageContainer.height();
        const imagePrefixPath = $imagePrefixPathInput.val();

        if (originalImageWidth === 0 || originalImageHeight === 0) {
            showAlert('请先上传图片，再进行复制操作!');
            return;
        }

        // let newImagePrefixPath = getFileNameAndPathRegex(imageSrc).directoryPath
        // let newOriginalImagePath = getFileNameAndPathRegex(imageSrc).fileName
        // localStorage.setItem('originalImagePath', newOriginalImagePath);
        // localStorage.setItem('imagePrefixPath', newImagePrefixPath || localStorage.getItem('imagePrefixPath'));
        // $("#imagePrefixPathInput").val(localStorage.getItem('imagePrefixPath'));
        // $originalImagePathDisplay.val(newOriginalImagePath);


        $('.text-item').each(function () {
            const $this = $(this);
            const currentTop = parseFloat($this.css('top'));
            const currentLeft = parseFloat($this.css('left'));
            const currentFontSize = parseFloat($this.css('font-size'));
            const currentPadding = $this.css('padding').split(' ').map(parseFloat);
            const color = $this.css('color');
            const bgColor = $this.css('background-color');
            const zIndex = $this.css('z-index');
            const borderRadius = parseFloat($this.css('border-radius'));

            const topRatio = currentTop / containerHeight * 100;
            const leftRatio = currentLeft / containerWidth * 100;
            const fontSizeRatio = currentFontSize / fixedBaseWidth;
            const paddingYRatio = currentPadding[0] / fixedBaseWidth;
            const paddingXRatio = currentPadding.length > 1 ? currentPadding[1] / fixedBaseWidth : paddingYRatio;
            const borderRadiusRatio = borderRadius / fixedBaseWidth;

            const textContent = this.innerText;
            const htmlWithBr = textContent.replace(/\n/g, '<br>');

            const styleRules = `
                position: absolute;
                top: ${topRatio}%;
                left: ${leftRatio}%;
                font-size: calc(var(--container-width) * ${fontSizeRatio});
                padding: calc(var(--container-width) * ${paddingYRatio}) calc(var(--container-width) * ${paddingXRatio});
                color: ${color};
                background-color: ${bgColor};
                z-index: ${zIndex};
                border-radius: calc(var(--container-width) * ${borderRadiusRatio});
                white-space: pre-wrap;
                font-weight: bold;
                text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
            `;
            const itemHtml = `<div class="text-item" style="${styleRules.replace(/\s+/g, ' ').trim()}">${htmlWithBr}</div>`;
            textItemsHtml.push(itemHtml);
        });

        const aspectRatio = (originalImageHeight / originalImageWidth) * 100;

        const completeHtml = `<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>图片标注</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="image-container" style="padding-top: ${aspectRatio}%;">
    <img src="${imageSrc}" alt="Annotated Image">
        ${textItemsHtml.join('\n')}
    </div>
</body>
</html>
`;
        return completeHtml;
    };

    $copyHtmlBtn.on('click', function () {
        const completeHtml = generateHtml($myImage.attr('src'));
        debugger
        if (completeHtml) {
            navigator.clipboard.writeText(completeHtml)
                .then(() => {
                    const settings = getSettings();
                    $copyHtmlBtn.text(settings.copyHtmlBtnSuccessText);
                    setTimeout(() => {
                        $copyHtmlBtn.text(settings.copyHtmlBtnText);
                    }, 2000);
                })
                .catch(err => {
                    console.error('复制失败: ', err);
                    showAlert('复制失败，请手动选择内容。');
                });
        }
    });

    $copyCustomHtmlBtn.on('click', function () {
        const imagePrefixPath = $imagePrefixPathInput.val();
        const originalImagePath = localStorage.getItem('originalImagePath');

        if (!originalImagePath) {
            showAlert('请输入图片前缀路径或先上传图片!');
            return;
        }

        var newImageUrl = ""
        if (originalImagePath.includes("data:image/png;base6")) { newImageUrl = originalImagePath }
        else {
            newImageUrl = `${imagePrefixPath == "" || imagePrefixPath.endsWith('/') ? originalImagePath : imagePrefixPath + '/'}${originalImagePath}`;
        }
        const completeHtml = generateHtml(newImageUrl);

        if (completeHtml) {
            navigator.clipboard.writeText(completeHtml)
                .then(() => {
                    const settings = getSettings();
                    $copyCustomHtmlBtn.text(settings.copyCustomHtmlBtnSuccessText);
                    setTimeout(() => {
                        $copyCustomHtmlBtn.text(settings.copyCustomHtmlBtnText);
                    }, 2000);
                })
                .catch(err => {
                    console.error('复制失败: ', err);
                    showAlert('复制失败，请手动选择内容。');
                });
        }
    });

    function parseHtmlAndUpdateState(htmlContent) {
        try {
            const parser = new DOMParser();
            const doc = parser.parseFromString(htmlContent, 'text/html');
            const $tempHtmlContainer = $(doc).find('[style*="padding-top"]').first();
            console.log('====================================');
            console.log($(doc).find('[style="padding-top"]'));
            console.log('====================================');

            if (!$tempHtmlContainer.length) {
                showAlert('未检测到有效的图片容器。');
                return;
            }

            const imageUrl = $tempHtmlContainer.find('img').attr('src');
            const imagePrefixPath = localStorage.getItem('imagePrefixPath') || '';
            console.log($tempHtmlContainer.find('img'), `打印输出`)


            if (imageUrl) {
                const tempImage = new Image();
                tempImage.onload = function () {
                    originalImageWidth = this.naturalWidth;
                    originalImageHeight = this.naturalHeight;
                    currentImageAspectRatio = originalImageWidth / originalImageHeight;

                    const newContainerWidth = baseImageWidth;
                    const newContainerHeight = newContainerWidth / currentImageAspectRatio;

                    $myImage.css('width', newContainerWidth + 'px');
                    $myImage.css('height', newContainerHeight + 'px');
                    $imageContainer.css('height', newContainerHeight + 'px');


                    $myImage.attr('src', imageUrl);
                    localStorage.setItem('savedImage', imageUrl);
                    localStorage.setItem('imageAspectRatio', currentImageAspectRatio);
                    localStorage.setItem('originalImageWidth', originalImageWidth);
                    localStorage.setItem('originalImageHeight', originalImageHeight);
                    debugger
                    let newImagePrefixPath = getFileNameAndPathRegex(imageUrl).directoryPath || imagePrefixPath
                    let newOriginalImagePath = getFileNameAndPathRegex(imageUrl).fileName || originalImagePath
                    localStorage.setItem('originalImagePath', newOriginalImagePath);
                    localStorage.setItem('imagePrefixPath', newImagePrefixPath);
                    $("#imagePrefixPathInput").val(newImagePrefixPath);
                    $originalImagePathDisplay.val(newOriginalImagePath);


                    $('.text-item').remove();
                    $tempHtmlContainer.find('.text-item').each(function () {
                        const $this = $(this);
                        const styleStr = $this.attr('style');

                        const topMatch = /top:\s*([\d.]+)%;/.exec(styleStr);
                        const leftMatch = /left:\s*([\d.]+)%;/.exec(styleStr);
                        const paddingYMatch = /padding:.*var\(--container-width\)\s*\*\s*([\d.]+)\s*\).*?var\(--container-width\)\s*\*\s*([\d.]+)\s*\);/.exec(styleStr);
                        const colorMatch = /color:\s*([^;]+);/.exec(styleStr);
                        const bgColorMatch = /background-color:\s*([^;]+);/.exec(styleStr);
                        const zIndexMatch = /z-index:\s*(\d+);/.exec(styleStr);
                        const borderRadiusMatch = /border-radius:.*var\(--container-width\)\s*\*\s*([\d.]+)\s*\);/.exec(styleStr);

                        let fontSizeRatio = defaultConfig.fontSizeRatio;
                        const fontSizeCalcMatch = /font-size:\s*calc\(var\(--container-width\)\s*\*\s*([\d.]+)\s*\);/.exec(styleStr);
                        if (fontSizeCalcMatch && fontSizeCalcMatch[1]) {
                            fontSizeRatio = parseFloat(fontSizeCalcMatch[1]);
                        } else {
                            const fontSizePxMatch = /font-size:\s*([\d.]+)px;/.exec(styleStr);
                            if (fontSizePxMatch && fontSizePxMatch[1]) {
                                const fixedPxSize = parseFloat(fontSizePxMatch[1]);
                                fontSizeRatio = fixedPxSize / baseImageWidth;
                            }
                        }

                        const top = topMatch ? parseFloat(topMatch[1]) : 0;
                        const left = leftMatch ? parseFloat(leftMatch[1]) : 0;
                        const paddingYRatio = paddingYMatch ? parseFloat(paddingYMatch[1]) : defaultConfig.paddingYRatio;
                        const paddingXRatio = paddingYMatch ? parseFloat(paddingYMatch[2]) : defaultConfig.paddingXRatio;
                        const color = colorMatch ? colorMatch[1] : defaultConfig.fontColor;
                        const bgColor = bgColorMatch ? bgColorMatch[1] : defaultConfig.bgColor;
                        const zIndex = zIndexMatch ? parseInt(zIndexMatch[1]) : defaultConfig.zIndex;
                        const borderRadiusRatio = borderRadiusMatch ? parseFloat(borderRadiusMatch[1]) : (defaultConfig.borderRadius / baseImageWidth);
                        const borderRadius = borderRadiusRatio * baseImageWidth;

                        const $textItem = $('<div class="text-item" contenteditable="false"></div>');
                        $textItem.html($this.html());

                        const fixedBaseWidth = baseImageWidth;

                        $textItem.css({
                            'left': left + '%',
                            'top': top + '%',
                            'font-size': (fontSizeRatio * fixedBaseWidth) + 'px',
                            'padding': `${(paddingYRatio * fixedBaseWidth)}px ${(paddingXRatio * fixedBaseWidth)}px`,
                            'color': color,
                            'background-color': bgColor,
                            'z-index': zIndex,
                            'border-radius': borderRadius + 'px'
                        });
                        $imageContainer.append($textItem);
                        initDraggableTextItems();
                        saveTextItems();
                        showAlert('HTML内容解析成功，图片和标注已加载！');
                    });
                };
                tempImage.src = imageUrl;
            } else {
                showAlert('HTML内容中未找到图片，无法解析。');
            }
        } catch (error) {
            console.error('HTML解析失败:', error);
            showAlert('HTML内容解析失败，请检查格式。');
        }
    }

    $htmlContentInput.on('paste', function (event) {
        const clipboardData = event.originalEvent.clipboardData || window.clipboardData;
        const pastedText = clipboardData.getData('text/plain') || clipboardData.getData('text/plain');
        console.log(pastedText, `打印输出`)
        debugger
        if (pastedText) {
            event.preventDefault();
            $(this).val(pastedText);
            parseHtmlAndUpdateState(pastedText);
        }
    });

    $parseHtmlBtn.on('click', function () {
        const htmlContent = $htmlContentInput.val();
        if (htmlContent) {
            parseHtmlAndUpdateState(htmlContent);
        } else {
            showAlert('请先粘贴HTML内容！');
        }
    });

    const imagePrefixPathInput = document.getElementById('imagePrefixPathInput');
    const originalImagePathDisplay = document.getElementById('originalImagePathDisplay');
    renderMask(imagePrefixPathInput, "imagePrefixPath", "image-prefix-mask1")
    renderMask(originalImagePathDisplay, "originalImagePath", "image-prefix-mask2", "right")
    // renderMask(originalImagePathDisplay, "originalImagePath", "image-prefix-mask2")
});


function renderMask($imagePrefixPathInput, $storegeImagePrefixPath, $maskName, horizontalDirection = "left") {
    // 获取需要添加遮罩的输入框元素
    // const imagePrefixPathInput = document.getElementById('imagePrefixPathInput');
    // 获取其父元素，以便在其中添加遮罩
    const parentDiv = $imagePrefixPathInput.parentNode;
    // 创建遮罩层元素
    const mask = document.createElement('div');
    mask.className = $maskName;
    let $imagePrefixPathInputWidth = $($imagePrefixPathInput).outerWidth(true); // 包括 margin
    // 设置遮罩层的样式，使其不可编辑和不可被选择
    mask.style.cssText = `
    position: absolute;
    top: 0;
    ${horizontalDirection}: 0;
    width: ${$imagePrefixPathInputWidth}px;
    height: 100%;
    cursor: pointer;
    z-index: 10;
    background-color: transparent;
    user-select: none;
`;
    // 将遮罩层添加到父元素中，使其覆盖在输入框上方
    parentDiv.style.position = 'relative'; // 确保父元素有定位
    parentDiv.appendChild(mask);
    // 在页面加载时，确保输入框是禁用和只读的，并且不可被选择
    $imagePrefixPathInput.disabled = true;
    $imagePrefixPathInput.readOnly = true;
    $imagePrefixPathInput.style.userSelect = 'none';
    // 为遮罩层添加双击事件监听器
    mask.addEventListener('dblclick', function () {
        // 隐藏遮罩层
        mask.style.display = 'none';
        // 激活输入框并使其可编辑和可选择
        $imagePrefixPathInput.disabled = false;
        $imagePrefixPathInput.readOnly = false;
        $imagePrefixPathInput.style.userSelect = 'auto';
        $imagePrefixPathInput.focus();
    });
    // 为输入框添加失去焦点事件监听器
    $imagePrefixPathInput.addEventListener('blur', function () {
        // 重新显示遮罩层
        mask.style.display = 'block';
        // 禁用输入框并使其不可被选择
        $imagePrefixPathInput.disabled = true;
        $imagePrefixPathInput.readOnly = true;
        console.log($(this).val());
        localStorage.setItem($storegeImagePrefixPath, $(this).val());
        $imagePrefixPathInput.style.userSelect = 'none';
    });
}



/**
 * 使用正则表达式从文件路径中提取文件名和目录路径。
 * @param {string} filePath - 文件的完整路径，例如 'a/b/c/xxx.png'。
 * @returns {{fileName: string, directoryPath: string}} - 包含文件名和目录路径的对象。
 */
function getFileNameAndPathRegex3(filePath) {
    // 正则表达式解释:
    // (.*)      - 捕获组1: 匹配任意字符零次或多次，尽可能多地匹配 (贪婪模式)。这会匹配整个路径。
    // \/        - 匹配一个字面量字符 '/'。
    // ([^/]+)   - 捕获组2: 匹配一个或多个非 '/' 字符。这会精确匹配文件名。
    const match = filePath.match(/(.*)\/([^/]+)/);

    // 如果匹配成功，match 数组将包含:
    // match[0]: 完整匹配的字符串 (例如 'a/b/c/xxx.png')
    // match[1]: 第一个捕获组 (目录路径，例如 'a/b/c')
    // match[2]: 第二个捕获组 (文件名，例如 'xxx.png')
    if (match) {
        return {
            fileName: match[2],
            directoryPath: match[1]
        };
    } else {
        // 如果没有斜杠匹配，则整个字符串都是文件名
        return {
            fileName: filePath,
            directoryPath: ''
        };
    }
}


/**
 * 从文件路径中提取文件名和目录路径。
 * @param {string} filePath - 文件的完整路径，例如 'a/b/c/xxx.png'。
 * @returns {{fileName: string, directoryPath: string}} - 包含文件名和目录路径的对象。
 */
function getFileNameAndPathRegex(filePath) {
    // 检查输入是否为字符串
    if (typeof filePath !== 'string') {
        return { fileName: '', directoryPath: '' };
    }

    // 使用lastIndexOf找到最后一个斜杠的位置
    const lastSlashIndex = filePath.lastIndexOf('/');

    // 如果没有找到斜杠，说明路径中只有文件名
    if (lastSlashIndex === -1) {
        return {
            fileName: filePath,
            directoryPath: ''
        };
    }

    // 使用slice分别提取文件名和目录路径
    const fileName = filePath.slice(lastSlashIndex + 1);
    const directoryPath = filePath.slice(0, lastSlashIndex);

    return {
        fileName: fileName,
        directoryPath: directoryPath
    };
}
